package com.geese.module.business.service.impl;

import com.geese.common.constants.BusinessConstants;
import com.geese.common.constants.Constants;
import com.geese.common.entity.ChannelDO;
import com.geese.common.entity.User;
import com.geese.common.vo.Page;
import com.geese.exception.BusinessException;
import com.geese.module.business.dao.ChannelMapper;
import com.geese.module.business.service.IChannelService;
import com.geese.module.business.vo.ChannelVO;
import com.geese.module.user.dao.UserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by huweiwei on 2017/3/17.
 */
@Service
public class ChannelServiceImpl implements IChannelService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ChannelMapper channelMapper;

    @Override
    public Map<String, Object> getChannelList(ChannelVO channelVO, Page page) {
        PageHelper.startPage(page.getCurrPage(), page.getPageSize(), " id DESC");
        List<User> channelList = userMapper.selectChannelList(channelVO);
        List<Map<String, Object>> list = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(channelList)) {
            List<Integer> ids = Lists.transform(channelList, new Function<User, Integer>() {
                @Override
                public Integer apply(User user) {
                    return user.getId();
                }
            });
            List<ChannelDO> channelDOList = channelMapper.selectListByUserIds(ids);
            Map<Integer, ChannelDO> channelDOMap = Maps.uniqueIndex(channelDOList, new Function<ChannelDO, Integer>() {
                @Override
                public Integer apply(ChannelDO channelDO) {
                    return channelDO.getUserId();
                }
            });
            for (User user : channelList) {
                Map<String, Object> temp = Maps.newHashMap();
                temp.put("id", user.getId());
                temp.put("username", user.getUsername());
                temp.put("mobile", user.getMobile());
                temp.put("area", channelDOMap.get(user.getId()).getArea());
                temp.put("quantity", channelDOMap.get(user.getId()).getQuantity());
                list.add(temp);
            }
        }
        PageInfo pages = new PageInfo(channelList);
        Map<String, Object> pageInfo = Maps.newHashMap();
        pageInfo.put(Constants.CURR_PAGE, pages.getPageNum());
        pageInfo.put(Constants.TOTAL_PAGE, pages.getPages());
        pageInfo.put(Constants.TOTAL, pages.getTotal());

        Map<String, Object> result = Maps.newHashMap();
        result.put(Constants.PAGE_INFO, pageInfo);
        result.put("channelList", list);
        return result;
    }

    @Override
    public void update(User user) {
//        User check = userMapper.findByUsername(user.getUsername());
//        if (null != check && !Objects.equals(check.getId(), user.getId())) {
//            throw new RuntimeException("渠道名已存在");
//        }
        if (!checkType(Lists.newArrayList(user.getId()))) {
            throw new BusinessException(120037);
        }
        if (userMapper.updateById(user) != 1) {
            throw new BusinessException(120036);
        }
    }

    @Override
    public void add(User user) {
        user.setEnable(1);
        user.setBlock(0);
        user.setUserType(BusinessConstants.CHANNEL_TYPE);
        userMapper.save(user);
        if (!(user.getId() > 0)) {
            throw new BusinessException(120033);
        }
    }

    @Override
    public void addChannel(String username, String mobile, String area) {

        User check = userMapper.selectByTypeAndMobile(BusinessConstants.CHANNEL_TYPE, mobile);
        if (check != null) {
            throw new BusinessException(120111);
        }
        User user = new User();
        user.setUsername(username);
        user.setMobile(mobile);
        user.setBlock(0);
        user.setEnable(1);
        user.setUserType(BusinessConstants.CHANNEL_TYPE);
        userMapper.save(user);
        if (!(user.getId() > 0)) {
            throw new BusinessException(120033);
        }
        ChannelDO channelDO = new ChannelDO();
        channelDO.setMobile(mobile);
        channelDO.setArea(area);
        channelDO.setEnable(1);
        channelDO.setQuantity(0);
        channelDO.setUserId(user.getId());
        channelMapper.insert(channelDO);
    }

    @Override
    public void delete(Integer id) {
        if (!checkType(Lists.newArrayList(id))) {
            throw new BusinessException(120037);
        }
        userMapper.remove(id);
        channelMapper.removeByUserId(id);
    }

    @Override
    public void deleteAll(List<Integer> ids) {
        if (!checkType(ids)) {
            throw new BusinessException(120037);
        }
        userMapper.removeBatch(ids);
        channelMapper.removeByUserIds(ids);
    }

    /**
     * 校验用户type是否等于渠道用户的type
     * @param ids
     * @return
     */
    private boolean checkType(List<Integer> ids) {
        List<User> userList = userMapper.selectListByIds(ids);
        for (User user : userList) {
            if (!Objects.equals(user.getUserType(), BusinessConstants.CHANNEL_TYPE)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public Map<String, Object> getAll() {
        List<User> userList = userMapper.selectChannelList(new ChannelVO());
        Map<String, Object> result = Maps.newHashMap();
        List<Map<String, Object>> data = Lists.newArrayList();
        for (User user : userList) {
            Map<String, Object> temp = Maps.newHashMap();
            temp.put("id", user.getId());
            temp.put("username", user.getUsername());
            temp.put("mobile", user.getMobile());
            data.add(temp);
        }
        result.put("channelList", data);
        return result;
    }

    @Override
    public void updateChannel(Integer id, String username, String mobile, String area) {
        User user = userMapper.findById(id);
        if (user == null || user.getUserType() != BusinessConstants.CHANNEL_TYPE) {
            throw new BusinessException(120110);
        }
        User check = userMapper.selectByTypeAndMobile(BusinessConstants.CHANNEL_TYPE, mobile);
        if (check != null && !Objects.equals(check.getId(), id)) {
            throw new BusinessException(120111);
        }
        user.setMobile(mobile);
        user.setUsername(username);
        userMapper.updateById(user);
        if (StringUtils.isNotBlank(area)) {
            ChannelDO channelDO = channelMapper.selectByUserId(user.getId());
            if (channelDO == null) {
                throw new BusinessException(120110);
            }
            channelDO.setArea(area);
            channelDO.setMobile(mobile);
            channelMapper.update(channelDO);
        }
    }
}
